import json
from datetime import datetime
from django import http
from django.core.paginator import Paginator
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection

from goods.constants import LIST_PER_PAGE
from meiduo_mall.utils import meiduo_category
from meiduo_mall.utils.meiduo_category import get_breadcrumb
from .models import GoodsCategory, SKU, GoodsVisitCount
from meiduo_mall.utils.response_code import RETCODE


class ListView(View):
    def get(self, request, category_id, page_num):
        '''
        :param category_id: 商品分类
        :param page_num: 页码
        :return: 商品列表页
        '''

        # 获取三级类别
        try:
            category3 = GoodsCategory.objects.get(pk=category_id)  # 主键是什么鬼
        except:
            return render(request, '404.html')
        # print(category3.name)
        # 分类
        categories = meiduo_category.get_categories()
        # 面包屑导航  parent什么鬼
        breadcrumb = get_breadcrumb(category3)
        # 热销
        # 当前商品展示
        skus = category3.sku_set.filter(is_launched=True)
        # 排序
        # 获取ｓｏｒｔ
        sort = request.GET.get('sort', 'default')

        if sort == 'price':
            skus = skus.order_by('price')
        elif sort == 'hot':
            skus = skus.order_by('-sales')
        else:
            skus = skus.order_by('-id')

        # 分页
        paginator = Paginator(skus, LIST_PER_PAGE)
        page = paginator.page(page_num)
        context = {
            'category': category3,
            'breadcrumb': breadcrumb,
            'page_skus': page,
            'categories': categories,
            'sort': sort,
            'page_num': page_num,
            'total_page': paginator.num_pages
        }
        return render(request, 'list.html', context)


class HotView(View):
    def get(self, request, category_id):
        # try:
        #     category3 = GoodsCategory.objects.get(pk=category_id) # 主键是什么鬼
        # except:
        #     return render(request, '404.html')
        skus = SKU.objects.filter(is_launched=True, category_id=category_id).order_by('-sales')[0:2]
        print(skus)
        hot_list = []
        for sku in skus:
            hot_list.append({
                'id': sku.id,
                'default_image_url': sku.default_image.url,
                'name': sku.name,
                'price': sku.price,
            })
        print(hot_list)
        return http.JsonResponse({
            'code': RETCODE.OK,
            'errmsg': 'ok',
            'hot_sku_list': hot_list
        })


class DetailView(View):
    def get(self, request, sku_id):
        # 分类　面包屑导航　先获取商品对象及分类对象
        try:
            sku = SKU.objects.get(id=sku_id, is_launched=True)
        except:
            return render(request, '404.html')
        category3 = sku.category
        # 分类
        categories = meiduo_category.get_categories()
        # 面包屑导航  parent什么鬼
        breadcrumb = get_breadcrumb(category3)
        # 热销排行
        # 商品名称价格图片
        price = sku.price
        name = sku.name
        default_image = sku.default_image

        # 商品详情spu对象
        spu = sku.spu

        # 当前spu ---> skus
        skus = spu.sku_set.filter(is_launched=True)
        options_sku_dict = {}
        for sku_info in skus:
            # ｓｋｕ所对应的信息集
            sku_specs = sku_info.specs.order_by('option_id')
            # 信息所对应的选项的ｉｄ   sku_specs
            options_id_list = [sku_spec.option_id for sku_spec in sku_specs]
            # 多个选项对应一个商品ｓｐｕ．ｉｄ的字典
            options_sku_dict[tuple(options_id_list)] = sku_info.id
        # print(options_sku_dict)
        # 当前商品的所有ｓｋｕ选项信息的对象查询集　如：红　64．．．

        sku_specs1 = sku.specs.order_by('option_id')
        specs_options_list = [option.option_id for option in sku_specs1]
        # 商品规格 spu规格查询集
        specs = spu.specs.all()
        spec_list = []
        for index, spec in enumerate(specs):
            # 当前ｓｐｕ规格的选项查询集　如： 红黄蓝 64 128
            options = spec.options.all()
            # 规格字典
            spec_dict = {
                'name': spec.name,  # 当前商品当前行规格
                'options': []  # 当前商品规格选项集
            }

            spec_list.append(spec_dict)
            for option in options:

                new_options_list = specs_options_list[:]
                new_options_list[index] = option.id
                option = {
                    'name': option.value,
                    'id': option.id,
                    'sku_id': options_sku_dict[tuple(new_options_list)]
                }
                # print(option['id'],specs_options_list,options_sku_dict[tuple(new_options_list)])
                if option['id'] in specs_options_list:
                    option['select'] = True
                else:
                    option['select'] = False
                # print(option)

                spec_dict['options'].append(option)

        context = {
            'categories': categories,
            'breadcrumb': breadcrumb,
            'price': price,
            'name': name,
            'default_image': default_image,
            'spu': spu,
            'category_id': category3.id,
            'sku_id': sku_id,
            'spec_list': spec_list,
        }
        return render(request, 'detail.html', context)


class DetailVisitHistoryView(View):
    def post(self, request, category_id):
        '''
        某天三级分类访问量
        :param request:
        :param category_id:
        :return:
        '''
        # 访问日期
        now = datetime.now()
        date = '%d-%d-%d' % (now.year, now.month, now.day)
        # 判断当天是否访问过
        try:
            visit = GoodsVisitCount.objects.get(category_id=category_id, date=date)
        # 没访问过添加访问量对象
        except:
            GoodsVisitCount.objects.create(count=1, category_id=category_id)
        # 访问过则直接加一
        else:
            visit.count += 1
            visit.save()
        return http.JsonResponse({
            'code': RETCODE.OK,
            'errmsg': 'ok',
        })


class HistoryView(View):
    def get(self, request):
        # 处理
        user = request.user
        if not user.is_authenticated:
            return http.JsonResponse({
                'code': RETCODE.PARAMERR,
                'errmsg': "未登录"
            })
        redis_conn = get_redis_connection('history')
        key = 'history%d' % user.id
        sku_ids = redis_conn.lrange(key, 0, -1)
        int_sku_ids =[int(sku_id) for sku_id in sku_ids]
        # ｓｋｕ对象
        skus = []
        for int_sku_id in int_sku_ids:
            sku = SKU.objects.get(id = int_sku_id)
            skus.append({
                'id':sku.id,
                'name':sku.name,
                'default_image_url':sku.default_image.url,
                'price':sku.price
            })

        # 响应
        return http.JsonResponse({
            'code':RETCODE.OK,
            'errmsg':'ok',
            'skus':skus,

        })
    def post(self, request):
        # 接受
        sku_id = json.loads(request.body.decode()).get('sku_id')
        # 验证
        if not all([sku_id]):
            return http.JsonResponse({
                'code': RETCODE.PARAMERR,
                'errmsg': "缺少库存编号"
            })
        user = request.user
        # 是否登录
        if not user.is_authenticated:
            return http.JsonResponse({
                'code': RETCODE.PARAMERR,
                'errmsg': "未登录"
            })
        try:
            sku = SKU.objects.get(id=sku_id)
        except:
            return http.JsonResponse({
                'code': RETCODE.PARAMERR,
                'errmsg': "库存编号无效"
            })

        # 处理　保存用户浏览数据
        redis_conn = get_redis_connection('history')
        # 管道
        redis_pl = redis_conn.pipeline()
        key = 'history%d' % user.id
        # 删除已有记录
        redis_pl.lrem(key, 0, sku.id)
        # 左侧添加当前记录
        redis_pl.lpush(key, sku.id)
        # 限制元素个数
        redis_pl.ltrim(key, 0, 4)
        redis_pl.execute()
        # 响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok'})



